home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / contrib / libgrx / pcx / pcxdump.c next >
Encoding:
C/C++ Source or Header  |  1994-03-31  |  4.7 KB  |  178 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <grx.h>
  5. #include <mousex.h>
  6. #include <io.h>
  7.  
  8. typedef unsigned char  uchar;
  9. typedef unsigned short ushort;
  10.  
  11. typedef struct {
  12.     uchar   maker;
  13.     uchar   version;
  14.     uchar   code;
  15.     uchar   bpp;                /* bits per pixel */
  16.     ushort  x1,y1,x2,y2;            /* image position */
  17.     ushort  hres,vres;                /* image size */
  18.     struct  { uchar R,G,B; } cmap[16];        /* palette */
  19.     uchar   vmode;                /* video mode to display it */
  20.     uchar   nplanes;                /* number of planes */
  21.     ushort  bpl;                /* bytes per scan line */
  22.     char    filler[128 - 68];
  23. } pcxhdr;
  24.  
  25. #if    defined(__GNUC__) && defined(__MSDOS__)
  26. #define MAX_COLORS     32768    /* maximum color graphics mode supported */
  27. #else
  28. #define MAX_COLORS     256    /* maximum color graphics mode supported */
  29. #endif
  30. #define MAX_OUTCOLORS  16    /* max number of simultaneous colors */
  31. #define MAX_WIDTH      1280    /* max horizontal image size */
  32.  
  33. static  int dumpCount = 0;
  34.  
  35. int pcxdump(char *fname)
  36. {
  37.     GrContext save,xfer;
  38.     pcxhdr hdr;
  39.     uchar  rows[4][MAX_WIDTH / 8];
  40.     char   colortable[MAX_COLORS];
  41.     char   pcxfname[100];
  42.     FILE  *pcxfile;
  43.     int    numcolors,block,fast;
  44.     int    ii,xx,yy,wdt,hgt;
  45.  
  46.     if(GrCurrentMode() < GR_320_200_graphics) return(0);
  47.     if(GrNumColors() > MAX_COLORS) return(0);
  48.     wdt = GrScreenX();
  49.     hgt = GrScreenY();
  50.     if(wdt > MAX_WIDTH) return(0);
  51.     if(fname == NULL) for( ; ; ) {
  52.         /* find a new file name */
  53.         sprintf(pcxfname,"dump%04d.pcx",dumpCount);
  54.         if(access(pcxfname,0) != 0) {
  55.         pcxfile = fopen(pcxfname,"wb");
  56.         if(pcxfile == NULL) return(0);
  57.         break;
  58.         }
  59.         if(++dumpCount >= 10000) return(0);
  60.     }
  61.     else {
  62.         strcpy(pcxfname,fname);
  63.         pcxfile = fopen(pcxfname,"wb");
  64.         if(pcxfile == NULL) return(0);
  65.     }
  66.     GrSaveContext(&save);
  67.     GrCreateContext(wdt,1,NULL,&xfer);
  68.     GrSetContext(&xfer);
  69.     memset(&hdr,0,sizeof(pcxhdr));
  70.     memset(colortable,-1,sizeof(colortable));
  71.     hdr.maker   = 10;
  72.     hdr.version = 5;
  73.     hdr.code    = 1;
  74.     hdr.x1        = 0;
  75.     hdr.y1        = 0;
  76.     hdr.x2        = wdt - 1;
  77.     hdr.y2        = hgt - 1;
  78.     hdr.hres    = wdt;
  79.     hdr.vres    = hgt;
  80.     hdr.bpp        = 1;
  81.     hdr.bpl        = (wdt + 7) / 8;
  82.     hdr.vmode   = 0x12;        /* standard 640x480 16 color VGA ! */
  83.     hdr.nplanes = 4;
  84.     numcolors   = 0;
  85.     fast  = (GrNumColors() == 256) ? 1 : 0;
  86.     block = MouseCursorIsDisplayed();
  87.     if(block) MouseEraseCursor();
  88.     fwrite(&hdr,sizeof(pcxhdr),1,pcxfile);
  89.     for(yy = 0; yy < hgt; yy++) {
  90.         uchar mask = 0x80;
  91.         int      bytepos = 0;
  92.         int      numbits = 0;
  93.         GrBitBlt(&xfer,0,0,&save,0,yy,wdt-1,yy,GrWRITE);
  94.         memset(rows,0,sizeof(rows));
  95.         for(xx = 0; xx < wdt; xx++) {
  96.         int  color    = fast ? xfer.gc_baseaddr[xx] : GrPixel(xx,0);
  97.         char outcolor = colortable[color];
  98.         if(outcolor < 0) {    /* new color */
  99.             int r,g,b;
  100.             GrQueryColor(color,&r,&g,&b);
  101.             for(ii = 0; ii < numcolors; ii++) {
  102.             if(hdr.cmap[ii].R != r) continue;
  103.             if(hdr.cmap[ii].G != g) continue;
  104.             if(hdr.cmap[ii].B != b) continue;
  105.             outcolor = ii;
  106.             break;
  107.             }
  108.             if(outcolor < 0) {
  109.             if(numcolors >= MAX_OUTCOLORS) goto error;
  110.             outcolor = ii = numcolors++;
  111.             hdr.cmap[ii].R = r;
  112.             hdr.cmap[ii].G = g;
  113.             hdr.cmap[ii].B = b;
  114.             }
  115.             colortable[color] = outcolor;
  116.         }
  117.         if(outcolor & 1) rows[0][bytepos] |= mask;
  118.         if(outcolor & 2) rows[1][bytepos] |= mask;
  119.         if(outcolor & 4) rows[2][bytepos] |= mask;
  120.         if(outcolor & 8) rows[3][bytepos] |= mask;
  121.         mask >>= 1;
  122.         if(++numbits == 8) {
  123.             mask    = 0x80;
  124.             numbits = 0;
  125.             bytepos++;
  126.         }
  127.         }
  128.         for(ii = 0; ii < 4; ii++) {
  129.         uchar *ptr    = rows[ii];
  130.         uchar  pixval = *ptr;
  131.         numbits = 0;
  132.         for(bytepos = hdr.bpl; --bytepos >= 0; ptr++) {
  133.             if(pixval != *ptr) {
  134.             while(numbits > 0x3f) {
  135.                 putc((0xc0 | 0x3f),pcxfile);
  136.                 putc(pixval,pcxfile);
  137.                 numbits -= 0x3f;
  138.             }
  139.             if(numbits > 0) {
  140.                 if((numbits > 1) || (pixval >= 0xc0))
  141.                 putc((0xc0 | numbits),pcxfile);
  142.                 putc(pixval,pcxfile);
  143.             }
  144.             numbits = 0;
  145.             }
  146.             pixval = *ptr;
  147.             numbits++;
  148.         }
  149.         while(numbits > 0x3f) {
  150.             putc((0xc0 | 0x3f),pcxfile);
  151.             putc(pixval,pcxfile);
  152.             numbits -= 0x3f;
  153.         }
  154.         if(numbits > 0) {
  155.             if((numbits > 1) || (pixval >= 0xc0))
  156.             putc((0xc0 | numbits),pcxfile);
  157.             putc(pixval,pcxfile);
  158.         }
  159.         }
  160.     }
  161.     if(ferror(pcxfile)) goto error;
  162.     if(block) MouseDisplayCursor();
  163.     GrSetContext(&save);
  164.     GrDestroyContext(&xfer);
  165.     fseek(pcxfile,0L,0);
  166.     fwrite(&hdr,sizeof(pcxhdr),1,pcxfile);
  167.     fclose(pcxfile);
  168.     return(1);
  169.       error:
  170.     if(block) MouseDisplayCursor();
  171.     GrSetContext(&save);
  172.     GrDestroyContext(&xfer);
  173.     fclose(pcxfile);
  174.     unlink(pcxfname);
  175.     return(0);
  176. }
  177.  
  178.